package org.linlinjava.litemall.wx.web;

import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.system.SystemConfig;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.wx.annotation.LoginUser;
import org.linlinjava.litemall.wx.vo.CartVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static org.linlinjava.litemall.wx.util.WxResponseCode.GOODS_NO_STOCK;
import static org.linlinjava.litemall.wx.util.WxResponseCode.GOODS_UNSHELVE;

/**
 * 用户购物车服务
 */
@RestController
@RequestMapping("/wx/cart")
@Validated
public class WxCartController {
    private final Log logger = LogFactory.getLog(WxCartController.class);

    @Autowired
    private LitemallCartService cartService;
    @Autowired
    private LitemallGoodsService goodsService;
    @Autowired
    private LitemallGoodsProductService productService;
    @Autowired
    private LitemallAddressService addressService;
    @Autowired
    private LitemallGrouponRulesService grouponRulesService;
    @Autowired
    private LitemallCouponService couponService;
    @Autowired
    private LitemallCouponUserService couponUserService;
    @Autowired
    private CouponVerifyService couponVerifyService;

    /**
     * 用户购物车信息
     *
     * @param userId 用户ID
     * @return 用户购物车信息
     */
    @GetMapping("index")
    public Object index(@LoginUser Integer userId) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        List<LitemallCart> list = cartService.queryByUid(userId);
        List<LitemallCart> cartList = new ArrayList<>();
        // TODO
        // 如果系统检查商品已删除或已下架，则系统自动删除。
        // 更好的效果应该是告知用户商品失效，允许用户点击按钮来清除失效商品。
        for (LitemallCart cart : list) {
            LitemallGoods goods = goodsService.findById(cart.getGoodsId());
            if (goods == null || !goods.getIsOnSale()) {
                cartService.deleteById(cart.getId());
                logger.debug("系统自动删除失效购物车商品 goodsId=" + cart.getGoodsId() + " productId=" + cart.getProductId());
            } else {
                // 检查多规格商品的规格是否存在
                if (goods.getIsMultipleSpec() && cart.getSpecificationIds() != null && cart.getSpecificationIds().length > 0) {
                    boolean specExists = true;
                    for (Integer specId : cart.getSpecificationIds()) {
                        LitemallGoodsSpecification spec = productService.findSpecificationById(specId);
                        if (spec == null) {
                            specExists = false;
                            break;
                        }
                    }
                    if (!specExists) {
                        cartService.deleteById(cart.getId());
                        logger.debug("系统自动删除规格失效的购物车商品 goodsId=" + cart.getGoodsId() + " specificationIds=" + Arrays.toString(cart.getSpecificationIds()));
                        continue;
                    }
                }
                cartList.add(cart);
            }
        }

        Integer goodsCount = 0;
        BigDecimal goodsAmount = new BigDecimal(0.00);
        Integer checkedGoodsCount = 0;
        BigDecimal checkedGoodsAmount = new BigDecimal(0.00);
        for (LitemallCart cart : cartList) {
            goodsCount += cart.getNumber();
            goodsAmount = goodsAmount.add(cart.getPrice().multiply(new BigDecimal(cart.getNumber())));
            if (cart.getChecked()) {
                checkedGoodsCount += cart.getNumber();
                checkedGoodsAmount = checkedGoodsAmount.add(cart.getPrice().multiply(new BigDecimal(cart.getNumber())));
            }
        }
        Map<String, Object> cartTotal = new HashMap<>();
        cartTotal.put("goodsCount", goodsCount);
        cartTotal.put("goodsAmount", goodsAmount);
        cartTotal.put("checkedGoodsCount", checkedGoodsCount);
        cartTotal.put("checkedGoodsAmount", checkedGoodsAmount);

        // 获取已选中的购物车商品
        List<LitemallCart> checkedCartList = cartList.stream()
                .filter(LitemallCart::getChecked)
                .collect(Collectors.toList());

        // 计算优惠券可用情况
        BigDecimal tmpCouponPrice = new BigDecimal(0.00);
        Integer tmpCouponId = 0;
        Integer tmpUserCouponId = 0;
        LitemallCoupon bestCoupon = null;

        // 只有选中商品才计算优惠券
        if (!checkedCartList.isEmpty()) {
            // 查询用户可用的优惠券
            List<LitemallCouponUser> couponUserList = couponUserService.queryAll(userId);

            // 处理所有优惠券，选择最优的一张
            for (LitemallCouponUser couponUser : couponUserList) {
                LitemallCoupon coupon = couponVerifyService.checkCoupon(userId, couponUser.getCouponId(), couponUser.getId(), checkedGoodsAmount, checkedCartList);
                if (coupon == null) {
                    continue;
                }

                // 检查是否满足优惠券使用条件
                if (checkedGoodsAmount.compareTo(coupon.getMin()) < 0) {
                    continue;
                }

                // 检查优惠券是否在有效期内
                LocalDateTime now = LocalDateTime.now();
                if (now.isBefore(coupon.getStartTime()) || now.isAfter(coupon.getEndTime())) {
                    continue;
                }

                // 选择优惠金额最大的优惠券
                if (tmpCouponPrice.compareTo(coupon.getDiscount()) == -1) {
                    tmpCouponPrice = coupon.getDiscount();
                    tmpCouponId = coupon.getId();
                    tmpUserCouponId = couponUser.getId();
                    bestCoupon = coupon;
                }
            }
        }

        // 处理优惠券分摊
        Map<Integer, BigDecimal> discountPerCart = new HashMap<>();

        // 先将所有购物车项的优惠金额设为0
        for (LitemallCart cart : cartList) {
            discountPerCart.put(cart.getId(), BigDecimal.ZERO);
        }

        // 如果有可用优惠券且有选中商品，则计算优惠分摊
        if (bestCoupon != null && tmpCouponPrice.compareTo(BigDecimal.ZERO) > 0 && !checkedCartList.isEmpty()) {
            // 在cartTotal中返回总优惠金额
            cartTotal.put("couponPrice", bestCoupon.getDiscount());
        }

        List<Map<String, Object>> cartMapList = new ArrayList<>();
        for (LitemallCart cart : cartList) {
            // 将分摊的优惠金额添加到购物车项中
            Map<String, Object> cartMap = new HashMap<>();
            cartMap.put("id", cart.getId());
            cartMap.put("goodsId", cart.getGoodsId());
            cartMap.put("goodsName", cart.getGoodsName());
            cartMap.put("goodsSn", cart.getGoodsSn());
            cartMap.put("number", cart.getNumber());
            cartMap.put("price", cart.getPrice());
            cartMap.put("specifications", cart.getSpecifications());
            cartMap.put("specificationIds", cart.getSpecificationIds());
            cartMap.put("picUrl", cart.getPicUrl());
            cartMap.put("checked", cart.getChecked());

            // 计算单个商品的总价
            BigDecimal itemAmount = cart.getPrice();
            cartMap.put("totalPrice", itemAmount);
            cartMap.put("couponPrice", BigDecimal.ZERO);
            cartMap.put("actualPrice", itemAmount);

            // 如果该商品使用了优惠券，添加优惠券标题
            if (bestCoupon != null) {
                cartMap.put("couponName", bestCoupon.getName());
            }

            cartMapList.add(cartMap);
        }

        // 添加优惠券信息到返回结果
        cartTotal.put("couponId", tmpCouponId);
        cartTotal.put("userCouponId", tmpUserCouponId);

        // 计算实际应付金额
        BigDecimal actualAmount = checkedGoodsAmount;
        if (bestCoupon != null && tmpCouponPrice.compareTo(BigDecimal.ZERO) > 0) {
            actualAmount = checkedGoodsAmount.subtract(tmpCouponPrice);
        }
        if (actualAmount.compareTo(BigDecimal.ZERO) < 0) {
            actualAmount = BigDecimal.ZERO;
        }

        // 计算运费
        BigDecimal freightPrice = BigDecimal.ZERO;
        // 只有在有选中商品时才计算运费
        if (!checkedCartList.isEmpty()) {
            BigDecimal freightMin = SystemConfig.getFreightLimit();
            BigDecimal freightValue = SystemConfig.getFreight();

            if (actualAmount.compareTo(freightMin) < 0) {
                freightPrice = freightValue;
            }
        }

        // 添加运费到实际应付金额
        actualAmount = actualAmount.add(freightPrice);

        // 在cartTotal中添加运费信息
        cartTotal.put("freightPrice", freightPrice);
        cartTotal.put("actualAmount", actualAmount);

        Map<String, Object> result = new HashMap<>();
        result.put("cartList", cartMapList);
        result.put("cartTotal", cartTotal);

        return ResponseUtil.ok(result);
    }

    /**
     * 加入商品到购物车
     * <p>
     * 如果已经存在购物车货品，则增加数量；
     * 否则添加新的购物车货品项。
     *
     * @param userId 用户ID
     * @param cartVo 购物车商品信息， { goodsId: xxx, specificationIds: [xxx, xxx], specificationsList: [xxx, xxx], number: xxx, price: xxx }
     * @return 加入购物车操作结果
     */
    @PostMapping("add")
    public Object add(@LoginUser Integer userId, @RequestBody CartVo cartVo) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        if (cartVo == null) {
            return ResponseUtil.badArgument();
        }

        Integer number = cartVo.getNumber().intValue();
        Integer goodsId = cartVo.getGoodsId();

        if (!ObjectUtils.allNotNull(number, goodsId)) {
            return ResponseUtil.badArgument();
        }
        if (number <= 0) {
            return ResponseUtil.badArgument();
        }

        // 判断商品是否可以购买
        LitemallGoods goods = goodsService.findById(goodsId);
        if (goods == null || !goods.getIsOnSale()) {
            return ResponseUtil.fail(GOODS_UNSHELVE, "商品已下架");
        }

        // 获取规格ID列表和规格描述列表
        List<Integer> specificationIds = Arrays.asList(cartVo.getSpecificationIds());
        List<String> specificationsList = cartVo.getSpecificationsList();

        // 后端计算价格
        BigDecimal calculatedPrice;
        if (goods.getIsMultipleSpec() && specificationIds != null && !specificationIds.isEmpty()) {
            // 多规格商品：只使用规格价格之和，不加基础价格
            BigDecimal totalSpecPrice = new BigDecimal("0.00");
            for (Integer specId : specificationIds) {
                LitemallGoodsSpecification spec = productService.findSpecificationById(specId);
                if (spec != null && spec.getPrice() != null) {
                    // 使用字符串构造BigDecimal，避免精度问题
                    totalSpecPrice = totalSpecPrice.add(BigDecimal.valueOf(spec.getPrice())).setScale(2, RoundingMode.HALF_UP);
                }
            }
            // 单价
            calculatedPrice = totalSpecPrice.setScale(2, RoundingMode.HALF_UP);
        } else {
            // 单规格商品，使用商品价格
            calculatedPrice = goods.getRetailPrice().setScale(2, RoundingMode.HALF_UP);
        }

        calculatedPrice = calculatedPrice.multiply(BigDecimal.valueOf(number)).setScale(2, RoundingMode.HALF_UP);

        // 验证前端传递的价格是否与后端计算的价格一致
        if (cartVo.getPrice() == null || cartVo.getPrice().compareTo(calculatedPrice) != 0) {
            return ResponseUtil.fail(400, "价格不一致，请刷新后重试");
        }

        // 判断购物车中是否存在此规格商品
        LitemallCart existCart = cartService.queryExist(goodsId, specificationIds, userId);

        if (existCart == null) {
            // 添加新的购物车商品
            LitemallCart cart = new LitemallCart();
            cart.setId(null);
            cart.setGoodsId(goodsId);
            cart.setGoodsName(goods.getName());
            cart.setGoodsSn(goods.getGoodsSn());
            cart.setNumber(cartVo.getNumber());
            cart.setPrice(calculatedPrice);
            cart.setUserId(userId);
            cart.setChecked(true);

            // 设置规格信息
            if (specificationsList != null && !specificationsList.isEmpty()) {
                cart.setSpecifications(specificationsList.toArray(new String[0]));
            } else {
                cart.setSpecifications(new String[0]);
            }

            // 设置规格ID信息
            if (specificationIds != null && !specificationIds.isEmpty()) {
                cart.setSpecificationIds(specificationIds.toArray(new Integer[0]));
            } else {
                cart.setSpecificationIds(new Integer[0]);
            }

            // 设置图片
            if (goods.getIsMultipleSpec() && specificationIds != null && !specificationIds.isEmpty()) {
                // 多规格商品，设置图片：如果有规格图片，使用第一个规格的图片
                LitemallGoodsSpecification firstSpec = productService.findSpecificationById(specificationIds.get(0));
                if (firstSpec != null && StringUtils.isNotEmpty(firstSpec.getPicUrl())) {
                    cart.setPicUrl(firstSpec.getPicUrl());
                } else {
                    cart.setPicUrl(goods.getPicUrl());
                }
            } else {
                // 单规格商品，使用商品图片
                cart.setPicUrl(goods.getPicUrl());
            }

            cartService.add(cart);
        } else {
            // 如果购物车已经存在此规格商品，则增加数量
            int num = existCart.getNumber() + number;
            existCart.setNumber((short) num);
            if (cartService.updateById(existCart) == 0) {
                return ResponseUtil.updatedDataFailed();
            }
        }

        return goodscount(userId);
    }

    /**
     * 立即购买
     * <p>
     * 和add方法的区别在于：
     * 1. 如果购物车内已经存在购物车货品，前者的逻辑是数量添加，这里的逻辑是数量覆盖
     * 2. 添加成功以后，前者的逻辑是返回当前购物车商品数量，这里的逻辑是返回对应购物车项的ID
     *
     * @param userId 用户ID
     * @param cartVo 购物车商品信息， { goodsId: xxx, specificationIds: [xxx, xxx], specificationsList: [xxx, xxx], number: xxx, price: xxx }
     * @return 立即购买操作结果
     */
    @PostMapping("fastadd")
    public Object fastadd(@LoginUser Integer userId, @RequestBody CartVo cartVo) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        if (cartVo == null) {
            return ResponseUtil.badArgument();
        }

        Integer number = cartVo.getNumber().intValue();
        Integer goodsId = cartVo.getGoodsId();

        if (!ObjectUtils.allNotNull(number, goodsId)) {
            return ResponseUtil.badArgument();
        }
        if (number <= 0) {
            return ResponseUtil.badArgument();
        }

        // 判断商品是否可以购买
        LitemallGoods goods = goodsService.findById(goodsId);
        if (goods == null || !goods.getIsOnSale()) {
            return ResponseUtil.fail(GOODS_UNSHELVE, "商品已下架");
        }

        // 获取规格ID列表和规格描述列表
        List<Integer> specificationIds = Arrays.asList(cartVo.getSpecificationIds());
        List<String> specificationsList = cartVo.getSpecificationsList();

        // 后端计算价格
        BigDecimal calculatedPrice;
        if (goods.getIsMultipleSpec() && specificationIds != null && !specificationIds.isEmpty()) {
            // 多规格商品：只使用规格价格之和，不加基础价格
            BigDecimal totalSpecPrice = new BigDecimal("0.00");
            for (Integer specId : specificationIds) {
                LitemallGoodsSpecification spec = productService.findSpecificationById(specId);
                if (spec != null && spec.getPrice() != null) {
                    // 使用字符串构造BigDecimal，避免精度问题
                    totalSpecPrice = totalSpecPrice.add(new BigDecimal(spec.getPrice())).setScale(2, BigDecimal.ROUND_HALF_UP);
                }
            }
            // 单价
            calculatedPrice = totalSpecPrice.setScale(2, BigDecimal.ROUND_HALF_UP);
        } else {
            // 单规格商品，使用商品价格
            calculatedPrice = goods.getRetailPrice().setScale(2, BigDecimal.ROUND_HALF_UP);
        }

        // 验证前端传递的价格是否与后端计算的价格一致
        if (cartVo.getPrice() == null || cartVo.getPrice().compareTo(calculatedPrice) != 0) {
            return ResponseUtil.fail(400, "价格不一致，请刷新后重试");
        }

        // 判断购物车中是否存在此规格商品
        LitemallCart existCart = cartService.queryExist(goodsId, specificationIds, userId);

        LitemallCart cart = new LitemallCart();
        if (existCart == null) {
            // 添加新的购物车商品
            cart.setId(null);
            cart.setGoodsId(goodsId);
            cart.setGoodsName(goods.getName());
            cart.setGoodsSn(goods.getGoodsSn());
            cart.setNumber(cartVo.getNumber());
            cart.setPrice(calculatedPrice);
            cart.setUserId(userId);
            cart.setChecked(true);

            // 设置规格信息
            if (specificationsList != null && !specificationsList.isEmpty()) {
                cart.setSpecifications(specificationsList.toArray(new String[0]));
            } else {
                cart.setSpecifications(new String[0]);
            }

            // 设置规格ID信息
            if (specificationIds != null && !specificationIds.isEmpty()) {
                cart.setSpecificationIds(specificationIds.toArray(new Integer[0]));
            } else {
                cart.setSpecificationIds(new Integer[0]);
            }

            // 设置图片
            if (goods.getIsMultipleSpec() && specificationIds != null && !specificationIds.isEmpty()) {
                // 多规格商品，设置图片：如果有规格图片，使用第一个规格的图片
                LitemallGoodsSpecification firstSpec = productService.findSpecificationById(specificationIds.get(0));
                if (firstSpec != null && StringUtils.isNotEmpty(firstSpec.getPicUrl())) {
                    cart.setPicUrl(firstSpec.getPicUrl());
                } else {
                    cart.setPicUrl(goods.getPicUrl());
                }
            } else {
                // 单规格商品，使用商品图片
                cart.setPicUrl(goods.getPicUrl());
            }

            cartService.add(cart);
        } else {
            // 立即购买的逻辑是数量覆盖
            existCart.setNumber(number.shortValue());
            if (cartService.updateById(existCart) == 0) {
                return ResponseUtil.updatedDataFailed();
            }
        }

        return ResponseUtil.ok(existCart != null ? existCart.getId() : cart.getId());
    }

    /**
     * 修改购物车商品货品数量
     *
     * @param userId 用户ID
     * @param body   购物车商品信息， { id: xxx, number: xxx }
     * @return 修改结果
     */
    @PostMapping("update")
    public Object update(@LoginUser Integer userId, @RequestBody String body) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        Integer id = JacksonUtil.parseInteger(body, "id");
        Integer number = JacksonUtil.parseInteger(body, "number");

        if (!ObjectUtils.allNotNull(id, number)) {
            return ResponseUtil.badArgument();
        }

        // 判断是否存在该购物车项
        LitemallCart existCart = cartService.findById(userId, id);
        if (existCart == null) {
            return ResponseUtil.badArgumentValue();
        }

        // 如果数量小于等于0，则直接删除
        if (number <= 0) {
            cartService.deleteById(id);
            return ResponseUtil.ok();
        }

        // 判断商品是否可以购买
        LitemallGoods goods = goodsService.findById(existCart.getGoodsId());
        if (goods == null || !goods.getIsOnSale()) {
            return ResponseUtil.fail(GOODS_UNSHELVE, "商品已下架");
        }

        // 更新购物车项
        existCart.setNumber(number.shortValue());
        if (cartService.updateById(existCart) == 0) {
            return ResponseUtil.updatedDataFailed();
        }
        return ResponseUtil.ok();
    }

    /**
     * 购物车商品货品勾选状态
     * <p>
     * 如果原来没有勾选，则设置勾选状态；如果商品已经勾选，则设置非勾选状态。
     *
     * @param userId 用户ID
     * @param body   购物车商品信息， { cartIds: xxx, isChecked: 1/0 }
     * @return 购物车信息
     */
    @PostMapping("checked")
    public Object checked(@LoginUser Integer userId, @RequestBody String body) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        if (body == null) {
            return ResponseUtil.badArgument();
        }

        List<Integer> cartIds = JacksonUtil.parseIntegerList(body, "cartIds");
        if (cartIds == null) {
            return ResponseUtil.badArgument();
        }

        Integer checkValue = JacksonUtil.parseInteger(body, "isChecked");
        if (checkValue == null) {
            return ResponseUtil.badArgument();
        }
        Boolean isChecked = (checkValue == 1);

        cartService.updateCheck(userId, cartIds, isChecked);
        return index(userId);
    }

    /**
     * 购物车商品删除
     *
     * @param userId 用户ID
     * @param body   购物车商品信息， { cartIds: xxx }
     * @return 购物车信息
     * 成功则
     * {
     * errno: 0,
     * errmsg: '成功',
     * data: xxx
     * }
     * 失败则 { errno: XXX, errmsg: XXX }
     */
    @PostMapping("delete")
    public Object delete(@LoginUser Integer userId, @RequestBody String body) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        if (body == null) {
            return ResponseUtil.badArgument();
        }

        List<Integer> cartIds = JacksonUtil.parseIntegerList(body, "cartIds");

        if (cartIds == null || cartIds.size() == 0) {
            return ResponseUtil.badArgument();
        }

        cartService.deleteByIds(cartIds, userId);
        return index(userId);
    }

    /**
     * 购物车商品货品数量
     * <p>
     * 如果用户没有登录，则返回空数据。
     *
     * @param userId 用户ID
     * @return 购物车商品货品数量
     */
    @GetMapping("goodscount")
    public Object goodscount(@LoginUser Integer userId) {
        if (userId == null) {
            return ResponseUtil.ok(0);
        }

        int goodsCount = 0;
        List<LitemallCart> cartList = cartService.queryByUid(userId);
        for (LitemallCart cart : cartList) {
            goodsCount += cart.getNumber();
        }

        return ResponseUtil.ok(goodsCount);
    }

    /**
     * 购物车下单
     *
     * @param userId    用户ID
     * @param cartId    购物车商品ID：
     *                  如果购物车商品ID是空，则下单当前用户所有购物车商品；
     *                  如果购物车商品ID非空，则只下单当前购物车商品。
     * @param addressId 收货地址ID：
     *                  如果收货地址ID是空，则查询当前用户的默认地址。
     * @param couponId  优惠券ID：
     *                  如果优惠券ID是空，则自动选择合适的优惠券。
     * @return 购物车操作结果
     */
    @GetMapping("checkout")
    public Object checkout(@LoginUser Integer userId, Integer cartId, Integer addressId, Integer couponId, Integer userCouponId, Integer grouponRulesId) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        // 收货地址
        LitemallAddress checkedAddress = null;
        if (addressId != null && !addressId.equals(0)) {
            checkedAddress = addressService.query(userId, addressId);
        }
        if (checkedAddress == null) {
            checkedAddress = addressService.findDefault(userId);
            // 如果仍然没有地址，则是没有收货地址
            // 返回一个空的地址id=0，这样前端则会提醒添加地址
            if (checkedAddress == null) {
                checkedAddress = new LitemallAddress();
                checkedAddress.setId(0);
                addressId = 0;
            } else {
                addressId = checkedAddress.getId();
            }
        }

        // 团购优惠
        BigDecimal grouponPrice = new BigDecimal(0.00);
        LitemallGrouponRules grouponRules = grouponRulesService.findById(grouponRulesId);
        if (grouponRules != null) {
            grouponPrice = grouponRules.getDiscount();
        }

        // 商品价格
        List<LitemallCart> checkedGoodsList = null;
        if (cartId == null || cartId.equals(0)) {
            checkedGoodsList = cartService.queryByUidAndChecked(userId);
        } else {
            LitemallCart cart = cartService.findById(userId, cartId);
            if (cart == null) {
                return ResponseUtil.badArgumentValue();
            }
            checkedGoodsList = new ArrayList<>(1);
            checkedGoodsList.add(cart);
        }
        BigDecimal checkedGoodsPrice = new BigDecimal(0.00);
        for (LitemallCart cart : checkedGoodsList) {
            //  只有当团购规格商品ID符合才进行团购优惠
            if (grouponRules != null && grouponRules.getGoodsId().equals(cart.getGoodsId())) {
                checkedGoodsPrice = checkedGoodsPrice.add(cart.getPrice().subtract(grouponPrice).multiply(new BigDecimal(cart.getNumber())));
            } else {
                checkedGoodsPrice = checkedGoodsPrice.add(cart.getPrice().multiply(new BigDecimal(cart.getNumber())));
            }
        }

        // 计算优惠券可用情况
        BigDecimal tmpCouponPrice = new BigDecimal(0.00);
        Integer tmpCouponId = 0;
        Integer tmpUserCouponId = 0;
        int tmpCouponLength = 0;
        List<LitemallCouponUser> couponUserList = couponUserService.queryAll(userId);
        for (LitemallCouponUser couponUser : couponUserList) {
            LitemallCoupon coupon = couponVerifyService.checkCoupon(userId, couponUser.getCouponId(), couponUser.getId(), checkedGoodsPrice, checkedGoodsList);
            if (coupon == null) {
                continue;
            }

            tmpCouponLength++;
            if (tmpCouponPrice.compareTo(coupon.getDiscount()) == -1) {
                tmpCouponPrice = coupon.getDiscount();
                tmpCouponId = coupon.getId();
                tmpUserCouponId = couponUser.getId();
            }
        }
        // 获取优惠券减免金额，优惠券可用数量
        int availableCouponLength = tmpCouponLength;
        BigDecimal couponPrice = new BigDecimal(0);
        // 这里存在三种情况
        // 1. 用户不想使用优惠券，则不处理
        // 2. 用户想自动使用优惠券，则选择合适优惠券
        // 3. 用户已选择优惠券，则测试优惠券是否合适
        if (couponId == null || couponId.equals(-1)) {
            couponId = -1;
            userCouponId = -1;
        } else if (couponId.equals(0)) {
            couponPrice = tmpCouponPrice;
            couponId = tmpCouponId;
            userCouponId = tmpUserCouponId;
        } else {
            LitemallCoupon coupon = couponVerifyService.checkCoupon(userId, couponId, userCouponId, checkedGoodsPrice, checkedGoodsList);
            // 用户选择的优惠券有问题，则选择合适优惠券，否则使用用户选择的优惠券
            if (coupon == null) {
                couponPrice = tmpCouponPrice;
                couponId = tmpCouponId;
                userCouponId = tmpUserCouponId;
            } else {
                couponPrice = coupon.getDiscount();
            }
        }

        // 根据订单商品总价计算运费，满88则免运费，否则8元；
        BigDecimal freightPrice = new BigDecimal(0.00);
        if (checkedGoodsPrice.compareTo(SystemConfig.getFreightLimit()) < 0) {
            freightPrice = SystemConfig.getFreight();
        }

        // 可以使用的其他钱，例如用户积分
        BigDecimal integralPrice = new BigDecimal(0.00);

        // 订单费用
        BigDecimal orderTotalPrice = checkedGoodsPrice.add(freightPrice).subtract(couponPrice).max(new BigDecimal(0.00));

        BigDecimal actualPrice = orderTotalPrice.subtract(integralPrice);

        Map<String, Object> data = new HashMap<>();
        data.put("addressId", addressId);
        data.put("couponId", couponId);
        data.put("userCouponId", userCouponId);
        data.put("cartId", cartId);
        data.put("grouponRulesId", grouponRulesId);
        data.put("grouponPrice", grouponPrice);
        data.put("checkedAddress", checkedAddress);
        data.put("availableCouponLength", availableCouponLength);
        data.put("goodsTotalPrice", checkedGoodsPrice);
        data.put("freightPrice", freightPrice);
        data.put("couponPrice", couponPrice);
        data.put("orderTotalPrice", orderTotalPrice);
        data.put("actualPrice", actualPrice);
        data.put("checkedGoodsList", checkedGoodsList);
        return ResponseUtil.ok(data);
    }
}
